package library

import (
	"context"
	"encoding/base64"
	"go.uber.org/zap"
	"hhos-mdijounery-server/global"
	"hhos-mdijounery-server/library/request"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
)

type MidJourneyApi struct {
	BaseMidJourneyApi
}

func NewMidJourneyApi() *MidJourneyApi {
	return &MidJourneyApi{
		BaseMidJourneyApi: *NewBaseMidJourneyApi(),
	}
}

// ImagineApi 文生图
func (m *MidJourneyApi) ImagineApi(ctx context.Context, params *request.ImagineReq) {
	defer func() {
		if err := recover(); err != nil {
			// 脚本处理失败，中断报警
			global.Logger.Error("failed to serve:", zap.Any("recover-err:", err))
		}
		// 处理完成逻辑处理
	}()

	// 获取token
	token, err := m.GetToken(ctx)
	if err != nil {
		global.Logger.Error("ImagineApi-GetToken-err: ", zap.Error(err))
	}

	// 文生图
	url := m.makeUrl(aiGenerateImage)

	imgUrlBase64 := m.getImgUrlBase64(params.ImgUrl)
	callbackUrl := m.makeCallbackUrl(midJourneyCallback)

	requestDataSign := map[string]string{
		"idempotent": params.Idempotent,
		"prompt":     params.Prompt,
		"img_base64": imgUrlBase64,
		"notify_url": callbackUrl,
	}

	sign := m.MakeSign(requestDataSign)

	headers := map[string]string{
		"token": token,
		"sign":  sign,
		"ts":    strconv.FormatInt(timeStamp, 10),
	}

	// 请求参数：先记日志，再加工图片的ImgBase64参数，防止日志过大
	requestData := &request.ImagineApiReq{
		Idempotent: params.Idempotent,
		Prompt:     params.Prompt,
		NotifyUrl:  callbackUrl,
	}

	global.Logger.Info("HttpPost-requestData: ", zap.Any("requestData", requestData))
	requestData.ImgBase64 = imgUrlBase64

	// 请求文生图
	result, err := HttpPost(url, headers, requestData)
	if err != nil {
		global.Logger.Error("imagine-post-err: ", zap.Error(err))
	}

	global.Logger.Info("result:", zap.String("result:", result))
}

// ChangeApi 绘画改变
func (m *MidJourneyApi) ChangeApi(ctx context.Context, params *request.ChangeReq) {

	defer func() {
		if err := recover(); err != nil {
			// 脚本处理失败，中断报警
			global.Logger.Error("ChangeApi-recover-err:", zap.Any("err", err))
		}
		// 处理完成逻辑处理
	}()

	// 获取token
	token, err := m.GetToken(ctx)
	if err != nil {
		global.Logger.Error("Imagine-GetToken-err:", zap.Error(err))
		return
	}

	// 绘画改变
	url := m.makeUrl(aiChangeImage)

	// 请求数据
	requestData := &request.ChangeApiReq{
		Idempotent: params.Idempotent,
		Action:     params.Action,
		Index:      params.Index,
		TaskId:     params.TaskId,
		NotifyUrl:  m.makeCallbackUrl(midJourneyCallback),
	}

	// 验签数据
	requestDataSign := map[string]string{
		"idempotent": params.Idempotent,
		"task_id":    params.TaskId,
		"action":     params.Action,
		"index":      strconv.FormatInt(params.Index, 10),
		"notify_url": m.makeCallbackUrl(midJourneyCallback),
	}

	sign := m.MakeSign(requestDataSign)
	headers := map[string]string{
		"token": token,
		"sign":  sign,
		"ts":    strconv.FormatInt(timeStamp, 10),
	}

	// 请求文生图
	global.Logger.Info("HttpPost:", zap.Any("requestData:", requestData))
	result, err := HttpPost(url, headers, requestData)
	if err != nil {
		global.Logger.Error("change-post-result:", zap.Error(err))
	}
	global.Logger.Info("result:", zap.String("result", result))
}

// 获取图片内容
func (m *MidJourneyApi) getImgUrlBase64(imgUrl string) string {

	// 为空则直接返回空
	if imgUrl == "" {
		return ""
	}

	// 获取图片
	resp, err := http.Get(imgUrl)
	if err != nil {
		global.Logger.Error("http-Get-resp-err:", zap.Error(err))
		return ""
	}

	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			global.Logger.Error("getImgUrlBase64-http-Get:", zap.Error(err))
		}
	}(resp.Body)

	if resp.StatusCode != http.StatusOK {
		global.Logger.Error("getImgUrlBase64-resp.StatusCode:", zap.Error(err))
	}

	imageData, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		global.Logger.Error("Error reading data:", zap.Error(err))
	}

	base64String := base64.StdEncoding.EncodeToString(imageData)
	return base64String
}
